
package com.kanjian.music;

import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;

public class UnCaughtExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler exceptionHandler;

    public UnCaughtExceptionHandler() {
        this.exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    };

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        String errorMsg = getException(ex);
        System.out.println(errorMsg);
        if (exceptionHandler != null) {
            exceptionHandler.uncaughtException(thread, ex);
        }
    }

    private String getException(Throwable exception) {

        NumberFormat theFormatter = new DecimalFormat("#0.");
        StringBuilder theErrReport = new StringBuilder();
        theErrReport.append(KanjianApplication.getContext().getPackageName()
                + " generated the following exception:\n");
        if (exception != null) {
            theErrReport.append(exception.toString() + "\n\n");
            // stack trace
            StackTraceElement[] theStackTrace = exception.getStackTrace();
            if (theStackTrace.length > 0) {
                theErrReport.append("======== Stack trace =======\n");
                int length = theStackTrace.length;
                for (int i = 0; i < length; i++) {
                    theErrReport.append(theFormatter.format(i + 1) + "\t"
                            + theStackTrace[i].toString() + "\n");
                }
                theErrReport.append("=====================\n\n");
            }
            Throwable theCause = exception.getCause();
            if (theCause != null) {
                theErrReport.append("======== Cause ========\n");
                theErrReport.append(theCause.toString() + "\n\n");
                theStackTrace = theCause.getStackTrace();
                int length = theStackTrace.length;
                for (int i = 0; i < length; i++) {
                    theErrReport.append(theFormatter.format(i + 1) + "\t"
                            + theStackTrace[i].toString() + "\n");
                }
                theErrReport.append("================\n\n");
            }
            PackageManager pm = KanjianApplication.getContext().getPackageManager();
            PackageInfo pi;
            try {
                pi = pm.getPackageInfo(KanjianApplication.getContext().getPackageName(), 0);
            } catch (NameNotFoundException e) {
                pi = new PackageInfo();
                pi.versionName = "unknown";
                pi.versionCode = 0;
            }
            Date now = new Date();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            theErrReport.append("======== Environment =======\n");
            theErrReport.append("Time=" + format.format(now) + "\n");
            theErrReport.append("Device=" + Build.FINGERPRINT + "\n");
            try {
                Field mfField = Build.class.getField("MANUFACTURER");
                theErrReport.append("Manufacturer=" + mfField.get(null) + "\n");
            } catch (SecurityException e) {
            } catch (NoSuchFieldException e) {
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            }
            theErrReport.append("Model=" + Build.MODEL + "\n");
            theErrReport.append("Product=" + Build.PRODUCT + "\n");
            theErrReport.append("App=" + KanjianApplication.getContext().getPackageName()
                    + ", version " + pi.versionName + " (build " + pi.versionCode + ")\n");
            theErrReport.append("=========================\nEnd Report");
        } else {
            theErrReport.append("the exception object is null\n");
        }

        return theErrReport.toString();

    }

}
